<script setup lang="ts">
import {
  NButton,
  NSpace,
  NDataTable,
  NInput,
  type DataTableColumns,
  NPagination,
  NForm,
  NFormItem,
  NSelect,
  NModal,
  useMessage,
  NTreeSelect,
  type TreeSelectOption,
  NEllipsis
} from 'naive-ui'
import { h, onMounted, reactive, ref, shallowRef } from 'vue'
import TableView from '@/components/TableView.vue'
import useFlush from '@/hooks/useFlush'
import { sendRequest } from '@/utils/api'
import type { HttpResponse, HttpResponsePagination } from '@/utils/http'
import type { CollectorTableRow } from '@/api/collector'
import { useRouter } from 'vue-router'
import VDialogContent from '@/views/OA/Common/DialogContent.vue'
import type { DicTreeModel } from '@/api/dic'
import axios from 'axios'

const message = useMessage()
const router = useRouter()
useFlush('flushCollectionTable', () => queryTableData())

interface TableQueryForm {
  collectorTags: string | null
  collectorTypeCode: string | null
  collectTypeCode: string | null
  idType: string | null
  regionCode: string | null
  remark: string | null
  sourceCode: string | null
  userName: string | null
}
const formData = reactive<TableQueryForm>({
  collectorTags: null,
  collectorTypeCode: null,
  collectTypeCode: null,
  idType: null,
  regionCode: null,
  remark: null,
  sourceCode: null,
  userName: null
})

const resetFormData = () => {
  formData.collectorTags = null
  formData.collectorTypeCode = null
  formData.collectTypeCode = null
  formData.idType = null
  formData.regionCode = null
  formData.remark = null
  formData.sourceCode = null
  formData.userName = null
}

const paginationReactive = reactive({
  page: 1,
  pageSize: 10,
  showSizePicker: true,
  pageSizes: [10, 20, 50, 100, 500],
  itemCount: 0,
  onChange: (page: number) => {
    paginationReactive.page = page
    queryTableData()
  },
  onUpdatePageSize: (pageSize: number) => {
    paginationReactive.pageSize = pageSize
    paginationReactive.page = 1
    queryTableData()
  }
})

const tableData = ref<CollectorTableRow[]>([])
const tableLoading = ref(false)
const queryTableData = async (flush = false) => {
  if (flush) paginationReactive.page = 1
  try {
    tableLoading.value = true
    const [error, res] = await sendRequest<HttpResponsePagination<CollectorTableRow>>({
      module: 'collector',
      api: 'list',
      override: {
        params: {
          limit: paginationReactive.pageSize,
          page: paginationReactive.page,
          ...formData
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)

    tableData.value = res.data.list
    paginationReactive.itemCount = res.data.totalCount
  } catch (error) {
    console.log(error)
  } finally {
    tableLoading.value = false
  }
}
const columns: DataTableColumns<CollectorTableRow> = [
  {
    title: '单位/个人名称',
    key: 'userName',
    ellipsis: {
      tooltip: {
        width: 300
      }
    }
  },
  {
    title: '类型',
    key: 'collectorTypeName',
    width: 100
  },
  {
    title: '来源',
    key: 'sourceName',
    width: 100
  },
  {
    title: '区域',
    key: 'regionName'
  },
  {
    title: '版本类型',
    key: 'collectTypeName',
    ellipsis: {
      tooltip: {
        width: 300
      }
    }
  },
  {
    title: '标签',
    key: 'collectorTags',
    render: ({ collectorTagsNames: tags }) => {
      if (!tags) return ''
      const items = tags.map((m) => {
        return h(
          NEllipsis,
          {
            style: {
              width: '80px',
              display: 'inline-block',
              height: '30px',
              lineHeight: '30px',
              textAlign: 'center',
              padding: '0 5px',
              backgroundColor: '#3399ff',
              color: '#fff'
            }
          },
          {
            default: () => m
          }
        )
      })
      return h(
        'div',
        {
          style: {
            display: 'flex',
            flexWrap: 'wrap',
            gap: '5px'
          }
        },
        items
      )
    }
  },
  {
    title: '备注',
    key: 'remark',
    width: 150,
    ellipsis: {
      tooltip: {
        width: 300
      }
    }
  },
  {
    title: '操作',
    key: 'action',
    align: 'center',
    width: 200,
    render: (e) => {
      return h(
        NSpace,
        {
          justify: 'center',
          wrap: false
        },
        {
          default: () => [
            h(
              NButton,
              {
                quaternary: true,
                type: 'primary',
                onClick: () => handleCollectionAction('u', e.id)
              },
              {
                default: () => '编辑'
              }
            ),
            h(
              NButton,
              {
                quaternary: true,
                type: 'error',
                onClick: () => handleCollectionAction('d', e.id)
              },
              {
                default: () => '删除'
              }
            ),
            h(
              NButton,
              {
                quaternary: true,
                type: 'primary',
                onClick: () => handleCollectionAction('r', e.id)
              },
              {
                default: () => '详情'
              }
            )
          ]
        }
      )
    }
  }
]

const deleteModalVisible = ref(false)
const deleteId = ref<number | null>(null)
const handleCollectionDelete = (id: number) => {
  deleteId.value = id
  deleteModalVisible.value = true
}
const confirmDelete = async () => {
  if (!deleteId.value) return
  console.log('confirm delete')
  try {
    const [error, res] = await sendRequest({
      module: 'collector',
      api: 'delete',
      override: {
        data: [deleteId.value]
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    queryTableData()
  } catch (error) {
    if (error instanceof Error) message.error(error.message)
  } finally {
    deleteModalVisible.value = false
  }
}
function handleCollectionAction(type: 'c' | 'r' | 'u' | 'd', id?: number) {
  if (type === 'd') return handleCollectionDelete(id!)
  router.push({
    name: type === 'c' ? 'CollectionAdd' : type === 'r' ? 'CollectionDetail' : 'CollectionEdit',
    params: {
      id
    },
    query: {
      type,
      redirect: router.currentRoute.value.fullPath
    }
  })
}

// 类型下拉框
const typeOptions = shallowRef<DicTreeModel[]>([])
const typeLoading = ref(false)
const queryTypeOptions = async () => {
  typeLoading.value = true
  try {
    const [error, res] = await sendRequest<HttpResponse<DicTreeModel[]>>({
      module: 'dic',
      api: 'getTree',
      override: {
        params: {
          dicCode: 'A63'
        }
      }
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    typeOptions.value = res.data[0] ? res.data[0].children || [] : []
  } catch (error) {
    console.error(error)
  } finally {
    typeLoading.value = false
  }
}

// 来源下拉框
const sourceOptions = shallowRef<DicTreeModel[]>([])
const sourceLoading = ref(false)
const querySourceOptions = async () => {
  sourceLoading.value = true
  try {
    const [error, res] = await sendRequest<HttpResponse<DicTreeModel[]>>({
      module: 'dic',
      api: 'getTree',
      override: {
        params: {
          dicCode: 'A64'
        }
      }
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    sourceOptions.value = res.data[0] ? res.data[0].children || [] : []
  } catch (error) {
    console.error(error)
  } finally {
    sourceLoading.value = false
  }
}

// 区域下拉框
function useQueryRegionOptions() {
  const loading = ref(false)
  const source = shallowRef(axios.CancelToken.source())
  const options = ref<TreeSelectOption[]>([])

  const query = async (option: TreeSelectOption) => {
    source.value.cancel('cancel')
    source.value = axios.CancelToken.source()

    try {
      loading.value = true
      const [error, res] = await sendRequest<HttpResponse<TreeSelectOption[]>>({
        module: 'sysRegion',
        api: 'list',
        uri: {
          code: option.regionCode as string
        },
        override: {
          cancelToken: source.value.token
        }
      })

      if (error) throw error
      if (res.code !== 0) throw new Error(res.msg)
      if (res.data) res.data.forEach((e) => (e.isLeaf = false))
      option.children = res.data.length ? res.data : undefined
      if (!option.children) option.isLeaf = true
    } catch (error) {
      if (axios.isCancel(error)) return
      if (error instanceof Error) message.error(error.message)
    } finally {
      loading.value = false
    }
  }
  return { options, loading, query }
}
const regionFeature = useQueryRegionOptions()

// 版本类型下拉框
const versionTypeOptions = ref<TreeSelectOption[]>([])
const versionTypeLoading = ref(false)
const queryVersionTypeOptions = async (code?: string) => {
  versionTypeLoading.value = true
  try {
    const [error, res] = await sendRequest<HttpResponse<TreeSelectOption[]>>({
      module: 'collector',
      api: 'versionListTreeAll',
      override: {
        params: {
          statusCode: 'A4901'
        }
      }
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    res.data.forEach((e) => (e.isLeaf = false))
    return res.data.length ? res.data : undefined
  } catch (error) {
    console.error(error)
  } finally {
    versionTypeLoading.value = false
  }
}
const handleVersionSelectLoad = async (option: TreeSelectOption) => {
  const child = await queryVersionTypeOptions(option.value as string)
  if (!child) option.isLeaf = true
  option.children = child
}

onMounted(() => {
  queryTableData()
  queryTypeOptions()
  querySourceOptions()
  queryVersionTypeOptions().then((e) => (versionTypeOptions.value = e || []))
  const tmp = {
    regionCode: '100000000000'
  } as TreeSelectOption
  regionFeature.query(tmp).then(() => {
    regionFeature.options.value = tmp.children || []
  })
})
</script>

<template>
  <TableView class="collector">
    <template #form>
      <NForm
        label-placement="left"
        :show-feedback="false"
        class="collector-form"
        @keydown.enter="queryTableData(true)"
      >
        <NFormItem label="单位/个人名称：">
          <NInput
            v-model:value="formData.userName"
            placeholder="请输入单位/个人名称"
            clearable
          />
        </NFormItem>
        <NFormItem label="类型：">
          <NSelect
            v-model:value="formData.collectorTypeCode"
            :options="typeOptions"
            :loading="typeLoading"
            placeholder="请选择类型"
            clearable
            filterable
            value-field="code"
            label-field="name"
          />
        </NFormItem>
        <NFormItem label="来源：">
          <NSelect
            v-model:value="formData.sourceCode"
            placeholder="请选择来源"
            :options="sourceOptions"
            :loading="sourceLoading"
            clearable
            filterable
            value-field="code"
            label-field="name"
          />
        </NFormItem>
        <NFormItem label="区域：">
          <NTreeSelect
            v-model:value="formData.regionCode"
            placeholder="请选择区域"
            clearable
            :loading="regionFeature.loading.value"
            :options="regionFeature.options.value"
            :on-load="regionFeature.query"
            key-field="regionCode"
            label-field="shortName"
            :consistent-menu-width="false"
          />
        </NFormItem>
        <NFormItem label="版本类型：">
          <NTreeSelect
            v-model:value="formData.collectTypeCode"
            :options="versionTypeOptions"
            :loading="versionTypeLoading"
            placeholder="请选择"
            clearable
            label-field="classificationName"
            key-field="classificationCode"
            children-field="childList"
            :consistent-menu-width="false"
          />
        </NFormItem>
        <NFormItem label="标签：">
          <NInput
            v-model:value="formData.collectorTags"
            placeholder="请输入标签"
            clearable
          />
        </NFormItem>
        <NFormItem label="备注：">
          <NInput
            v-model:value="formData.remark"
            placeholder="请输入备注"
            clearable
          />
        </NFormItem>

        <NSpace>
          <NButton
            :disabled="tableLoading"
            :loading="tableLoading"
            color="#6CB187"
            ghost
            style="min-width: 78rem"
            @click="queryTableData(true)"
          >
            查询
          </NButton>
          <NButton
            :disabled="tableLoading"
            color="#6CB187"
            style="min-width: 78rem"
            ghost
            @click="resetFormData"
          >
            重置
          </NButton>
        </NSpace>

        <NButton
          color="#6CB187"
          class="collector-add-button"
          @click="handleCollectionAction('c')"
        >
          新增
        </NButton>
      </NForm>
    </template>
    <template #table="props">
      <NDataTable
        v-bind="props"
        :data="tableData"
        :columns="columns"
        :loading="tableLoading"
        bordered
      />
    </template>
    <template #pagination>
      <NPagination
        show-size-picker
        show-quick-jumper
        :page-sizes="paginationReactive.pageSizes"
        :item-count="paginationReactive.itemCount"
        :page="paginationReactive.page"
        :page-size="paginationReactive.pageSize"
        @update:page="paginationReactive.onChange"
        @update:page-size="paginationReactive.onUpdatePageSize"
      >
        <template #suffix>页</template>
        <template #prefix>
          <span style="font-size: 14px">共{{ paginationReactive.itemCount }}条</span>
        </template>
      </NPagination>
    </template>
  </TableView>

  <NModal
    :auto-focus="false"
    v-model:show="deleteModalVisible"
  >
    <VDialogContent
      @close="deleteModalVisible = false"
      @submit="confirmDelete"
      title="删除提示"
    >
      <div style="width: 300rem; height: 100rem; text-align: center; line-height: 100rem">
        您确定要删除吗?
      </div>
    </VDialogContent>
  </NModal>
</template>

<style scoped lang="scss">
.collector {
  padding: 29rem 30rem;
  gap: 25rem 0;
}

.collector-form {
  display: flex;
  gap: 10rem;

  .n-form-item {
    flex: 0 0 260rem;
  }

  .n-form-item:nth-child(n + 2) {
    flex: 1;
  }

  .collector-add-button {
    width: 78rem;
    margin-left: auto;
  }
}

@media screen and (max-width: 1919px) {
  .collector-form {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 15rem 20rem;
  }

  .collector-add-button {
    grid-column: 5 / -1;
  }
}
</style>
